package gorpc

import (
	"errors"

	pb "gorpc/pb"

	"google.golang.org/protobuf/proto"
)

// MessageProtobufCoder protobuf消息编码器，对应C++的CMessageProtobufCoder
type MessageProtobufCoder struct{}

// NewMessageProtobufCoder 创建消息编码器
func NewMessageProtobufCoder() *MessageProtobufCoder {
	return &MessageProtobufCoder{}
}

// Encode 将消息编码为字节数组
func (c *MessageProtobufCoder) Encode(msg *RPCMessage) ([]byte, error) {
	if msg == nil {
		return nil, errors.New("message is nil")
	}

	// 创建protobuf消息包
	pbMessage := &pb.MessagePacket{
		Msgid: msg.GetMessageID(),
		Body:  msg.GetMessage(),
		Props: make(map[string]string),
	}

	// 复制属性
	for k, v := range msg.GetProps() {
		pbMessage.Props[k] = v
	}

	// 使用proto.Marshal序列化为二进制数据
	return proto.Marshal(pbMessage)
}

// Decode 将字节数组解码为消息
func (c *MessageProtobufCoder) Decode(data []byte) (*RPCMessage, error) {
	if len(data) == 0 {
		return nil, errors.New("data is empty")
	}

	// 创建protobuf消息包对象
	pbMessage := &pb.MessagePacket{}

	// 使用proto.Unmarshal反序列化数据
	if err := proto.Unmarshal(data, pbMessage); err != nil {
		return nil, err
	}

	// 创建消息对象并填充数据
	msg := NewMessage()
	msg.SetMessageID(pbMessage.Msgid)
	msg.SetMessage(pbMessage.Body)

	// 复制属性
	if pbMessage.Props != nil {
		for k, v := range pbMessage.Props {
			msg.SetProp(k, v)
		}
	}

	return msg, nil
}
